﻿/// <summary>
/// data   :2016-05-03
/// author :fanzhengyong
/// 自定义事件管理
/// </summary>

using UnityEngine;
using System.Collections;
using System.Collections.Generic;

namespace UEngine
{
    public struct GameEventParam
    {
        public int    code;
        public object data;
        public string arg0;
        public string arg1;

        public GameEventParam(int code)
        {
            this.code = code;
            this.data = null;
            this.arg0 = null;
            this.arg1 = null;
        }

        public GameEventParam(int code, object data)
        {
            this.code = code;
            this.data = data;
            this.arg0 = null;
            this.arg1 = null;
        }

        public GameEventParam(int code, string arg0, object data)
        {
            this.code = code;
            this.data = data;
            this.arg0 = arg0;
            this.arg1 = null;
        }

        public GameEventParam(int code, string arg0, string arg1, object data)
        {
            this.code = code;
            this.data = data;
            this.arg0 = arg0;
            this.arg1 = arg1;
        }
    }


    public delegate void GameEventDelegate(GameEventParam evt);

    public struct GameEvent
    {
        public GameEventParam    m_gameEventParam;
        public GameEventDelegate m_gameEventDelegate;
    }

    public class GameEventManager
    {
        private static GameEventManager m_instance = null;
        public static GameEventManager Instance()
        {
            if (m_instance == null)
            {
                m_instance = new GameEventManager();
            }
            return m_instance;
        }

        private Dictionary<int, GameEventDelegate> m_dictDelegates
            = new Dictionary<int, GameEventDelegate>();

        private List<GameEvent> m_listGameEvent
            = new List<GameEvent>();

        public void RegisteHandle(int code, GameEventDelegate handler)
        {
            if (m_dictDelegates.ContainsKey(code))
            {
                m_dictDelegates[code] += handler;
            }
            else
            {
                m_dictDelegates.Add(code, handler);
            }
        }

        public void UnRegisteHandle(int code, GameEventDelegate handler)
        {
            if (m_dictDelegates.ContainsKey(code))
            {
                m_dictDelegates[code] -= handler;

            }
        }

        public void PushEvent(int code)
        {
            GameEventDelegate handler;

            if (m_dictDelegates.TryGetValue(code, out handler))
            {
                GameEventParam param          = new GameEventParam(code);
                GameEvent      gameEvent      = new GameEvent();

                gameEvent.m_gameEventDelegate = handler;
                gameEvent.m_gameEventParam    = param;

                m_listGameEvent.Add(gameEvent);
            }
        }

        public void PushEvent(int code, object data)
        {
            GameEventDelegate handler;

            if (m_dictDelegates.TryGetValue(code, out handler))
            {
                GameEventParam param          = new GameEventParam(code, data);
                GameEvent      gameEvent      = new GameEvent();

                gameEvent.m_gameEventDelegate = handler;
                gameEvent.m_gameEventParam    = param;

                m_listGameEvent.Add(gameEvent);
            }
        }

        public void PushEvent(GameEventParam param)
        {
            GameEventDelegate handler;

            if (m_dictDelegates.TryGetValue(param.code, out handler))
            {
                GameEvent gameEvent           = new GameEvent();

                gameEvent.m_gameEventDelegate = handler;
                gameEvent.m_gameEventParam    = param;

                m_listGameEvent.Add(gameEvent);
            }
        }

        private void ProcessEvent()
        {
            if (m_listGameEvent.Count > 0)
            {
                foreach (GameEvent gameEvent in m_listGameEvent)
                {
                    gameEvent.m_gameEventDelegate(gameEvent.m_gameEventParam);
                }
                m_listGameEvent.Clear();
            }
        }

        public void Update()
        {
            ProcessEvent();
        }
    }
}
